home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1994 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee,
- * provided that (i) the above copyright notices and this permission
- * notice appear in all copies of the software and related documentation,
- * and (ii) the name of Silicon Graphics may not be used in any
- * advertising or publicity relating to the software without the specific,
- * prior written permission of Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL,
- * INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY
- * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
- * OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
- /*
- * ConvSharpenBlur - Demonstrate sharpenening and bluring of an image using
- * convolution.
- *
- * Keys:
- * Home - Set sharpness to 0 (neutral)
- * Up/Down - increase/decrease sharpness by 0.25
- * s - toggle histogram display
- * m - print min max value.
- * i - print sharpness value
- * x/y - toggle x/y mirroring of image
- * h/? - help
- * Esc - quit
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <GL/glx.h>
- #include <X11/keysym.h>
- #include "xwindow.h"
-
- #define RECT_SIZE 512
- #define WIN_SIZE 1.5*RECT_SIZE
- #define XORG 0.25*RECT_SIZE
- #define YORG 0.25*RECT_SIZE
-
- GLubyte buf1[RECT_SIZE][RECT_SIZE][3];
-
- static float sharpness = 0;
-
- static GLboolean doHistogram = GL_FALSE;
-
- GLint curPos[2] = {XORG, YORG};
- Display *dpy;
- Window win;
- GLint xFlip = 1, yFlip = 1;
-
- void render(void);
- void getMinMax(void);
-
- #if defined(GL_EXT_convolution) && defined(GL_EXT_histogram)
-
- void
- main(int argc, char* argv[])
- {
- int visualAttr[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, None};
- GLboolean done = GL_FALSE;
- GLXContext ctx;
- int yi, xi;
- const GLubyte *extensionsString;
-
- if (argc > 1) {
- fprintf(stderr, "usage: %s [-h for help]\n", argv[0]);
- fprintf(stderr,
- "\tInteractively, `h/?' keys provide description of\
- interface\n");
- exit (argv[1][0] == '-' && argv[1][1] == 'h' ?
- EXIT_SUCCESS : EXIT_FAILURE);
- }
-
-
- createWindowAndContext(&dpy, &win, &ctx, 100, 100, WIN_SIZE, WIN_SIZE,
- GL_TRUE, NULL, visualAttr, "Convolve");
- extensionsString = glGetString(GL_EXTENSIONS);
- /*
- * Check for convolution extension.
- */
- if (extensionsString == NULL ||
- !strstr((const char *) extensionsString, "EXT_convolution")) {
- /*
- * HACK - Convolution is not formally advertised. Try using it anyhow.
- */
- glDisable(GL_CONVOLUTION_2D_EXT);
- if (glGetError() != GL_NO_ERROR) {
- fprintf(stderr, "Sorry convolution is not supported by the renderer\n");
- exit(EXIT_FAILURE);
- } else
- fprintf(stderr, "Assuming EXT_convolution supported but not\
- advertised\n");
- }
- /*
- * Check for histogram extension.
- */
- if (!strstr((const char *) extensionsString, "EXT_histogram")) {
- /*
- * HACK - Histogram is not formally advertised. Try getting it anyhow.
- */
- glDisable(GL_HISTOGRAM_EXT);
- if (glGetError() != GL_NO_ERROR) {
- fprintf(stderr, "Sorry histogram is not supported in the renderer\n");
- exit(EXIT_FAILURE);
- } else
- fprintf(stderr, "Assuming EXT_histogram supported but not\
- advertised\n");
- }
- /* Create Image */
- for (yi = 0; yi < RECT_SIZE; yi++)
- for (xi = 0; xi < RECT_SIZE; xi++) {
- buf1[yi][xi][0] = xi & 0xff;
- buf1[yi][xi][1] = (xi^yi) & 0xff;
- buf1[yi][xi][2] = yi & 0xff;
- }
-
-
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, RECT_SIZE);
- glViewport(0, 0, WIN_SIZE, WIN_SIZE);
- glLoadIdentity();
- glOrtho(0, WIN_SIZE, 0, WIN_SIZE, -1, 1);
-
- glClearColor(0.1, 0.4, 0.8, 0.);
-
- /*
- * Select histogram and minmax statistic to RGBA (even though we're only
- * going to read RGB). As they are not used together both are "sink"ed
- * (no drawing to frame buffer). If histogram and minmax were used
- * together, then we would only sink minmax (comes last).
- */
- glMinmaxEXT(GL_MINMAX_EXT, GL_RGBA, GL_TRUE);
- glHistogramEXT(GL_HISTOGRAM_EXT, 4096, GL_RGBA, GL_TRUE);
-
- while (!done) {
- XEvent event;
-
- XNextEvent(dpy, &event);
- switch (event.type) {
- case KeyPress:
- switch (XLookupKeysym(&event.xkey, 0)) {
- case XK_Escape:
- done = GL_TRUE;
- break;
- case XK_i:
- case XK_I:
- printf("Sharpeness is %g\n",sharpness);
- break;
- case XK_m:
- getMinMax();
- break;
- case XK_s:
- doHistogram = !doHistogram;
- printf("Histogram is %s\n", doHistogram ? "ON" : "OFF");
- render();
- break;
- case XK_x:
- xFlip *= -1;
- curPos[0] -= RECT_SIZE * xFlip;
- render();
- break;
- case XK_y:
- yFlip *= -1;
- curPos[1] -= RECT_SIZE * yFlip;
- render();
- break;
- case XK_Up:
- if (sharpness < 10) {
- sharpness += 0.25;
- render();
- }
- break;
- case XK_Home:
- sharpness = 0;
- render();
- break;
- case XK_Down:
- if (sharpness > -10) {
- sharpness -= 0.25;
- render();
- }
- break;
- case XK_h:
- case XK_H:
- case XK_question:
- printf("Keys:\tHome - Set sharpness to 0 (neutral)\n");
- printf("\tUp/Down - increase/decrease sharpness\n");
- printf("\ts - toggle histogram display\n");
- printf("\tm - print min max value.\n");
- printf("\ti - print sharpness value\n");
- printf("\tx/y - toggle x/y mirroring of image\n");
- printf("\th/? - help\n");
- printf("\tEsc - quit\n");
- break;
- }
- break;
- case DestroyNotify:
- done = GL_TRUE;
- break;
- case Expose:
- render();
- break;
- }
- }
- }
-
- /*
- * Define the convolution filter.
- * 0 means no filtering.
- * Positive/Negative mean sharpen/blur.
- * When filtering, a separable radially symetric 5x5 kernel is used.
- */
- void
- setFilter(float sharpness /* [-10..10] */)
- {
- float row[5];
- float k0, k1, kscale;
- if (sharpness != 0.0) {
- if (sharpness < 0.0) {
- k0 = 0.15 - sharpness * 0.285;
- k1 = -0.6 - sharpness * 0.360;
- } else {
- k0 = 0.15 - sharpness * 0.045;
- k1 = -0.6 - sharpness * 0.045;
- }
-
- kscale = 1/(2*k0 + 2*k1 + 3);
- row[0] = row[4] = k0 * kscale;
- row[1] = row[3] = k1 * kscale;
- row[2] = 3 * kscale;
- glSeparableFilter2DEXT(GL_SEPARABLE_2D_EXT, GL_LUMINANCE,
- 5, 5, GL_LUMINANCE, GL_FLOAT, row, row);
- glEnable(GL_SEPARABLE_2D_EXT);
- } else
- glDisable(GL_SEPARABLE_2D_EXT);
- }
-
- /*
- * Retrieve and print the image min and max component values.
- */
- void
- getMinMax()
- {
- GLfloat minmax[6];
-
- glEnable(GL_MINMAX_EXT);
- glResetMinmaxEXT(GL_MINMAX_EXT);
- glReadBuffer(GL_FRONT);
- glCopyPixels(XORG, YORG, RECT_SIZE, RECT_SIZE, GL_COLOR);
- glReadBuffer(GL_BACK);
- glGetMinmaxEXT(GL_MINMAX_EXT, GL_TRUE, /* Reset */
- GL_RGB, GL_FLOAT, minmax);
- printf("Min (%g %g %g) Max (%g %g %g)\n",
- minmax[0], minmax[1], minmax[2],
- minmax[3], minmax[4], minmax[5]);
- glDisable(GL_MINMAX_EXT);
- }
-
- /*
- * Retrieve and draw the image histogram.
- */
- void
- getHistogram(void)
- {
- GLfloat hist[3*4096], *histp;
- static const float colors[9] = {1, 0, 0, 0, 1, 0, 0, 0, 1};
- int i,j;
-
- glDisable(GL_SEPARABLE_2D_EXT);
- glEnable(GL_HISTOGRAM_EXT);
- glResetHistogramEXT(GL_HISTOGRAM_EXT);
- glCopyPixels(XORG, YORG, RECT_SIZE, RECT_SIZE, GL_COLOR);
- glGetHistogramEXT(GL_HISTOGRAM_EXT, GL_TRUE, /* reset */
- GL_RGB, GL_FLOAT, hist);
- glDisable(GL_HISTOGRAM_EXT);
- for (j = 0; j < 3; j++) {
- glColor3fv(&colors[3*j]);
- histp = &hist[j];
- glBegin(GL_LINE_STRIP);
- for (i = 0; i < 4096; i++, histp += 3) {
- glVertex2f(10 + i * ((GLfloat) WIN_SIZE - 20)/4096,
- 50 + (WIN_SIZE - 100)/3.0 * (j +
- 50**histp/(RECT_SIZE*RECT_SIZE)));
- }
- glEnd();
- }
- }
-
- /*
- * Render a single frame.
- */
- void
- render()
- {
- glClear(GL_COLOR_BUFFER_BIT);
-
- glDisable(GL_SEPARABLE_2D_EXT);
- glPixelZoom(1, 1);
- glRasterPos2i(XORG, YORG);
- glDrawPixels(RECT_SIZE, RECT_SIZE, GL_RGB, GL_UNSIGNED_BYTE, buf1);
-
- glPixelZoom(xFlip, yFlip);
- glRasterPos2iv(curPos);
- setFilter(sharpness);
- glCopyPixels(XORG, YORG, RECT_SIZE, RECT_SIZE, GL_COLOR);
- if (doHistogram)
- getHistogram();
- glXSwapBuffers(dpy, win);
- }
- #else /* either histogram on convolution is not part of the library */
- /* Generate a compiler error with a message */
- Sorry CONVOLUTION OR HISTOGRAM is not supported by the library.
- #endif
-